﻿using Newtonsoft.Json.Linq;
using System;
using System.Threading.Tasks;
using UnityEngine;
// using MsgPack;
// using MsgPack.Serialization;

namespace HyxFrame.Core
{

    public abstract class ConfigLoadBase
    {
        public bool IsLoaded
        {
            get { return m_isLoaded; }
        }
        private bool m_isLoaded = false;

        public void Load()
        {
            if (IsLoaded)
                return;

            OnLoad();
        }

        public void Unload(bool force = false)
        {
            if (!force && !IsLoaded)
                return;

            OnUnload();
        }

        protected virtual void OnLoad()
        {
            m_isLoaded = true;
        }

        // 定义一个受保护的抽象方法，用于在卸载时调用
        protected virtual void OnUnload()
        {
            m_isLoaded = false;
        }




        public async Task<string> ReadConfigAsync(string fileName)
        {
            var s = await ResourceManager.Instance.ReadJsonData(fileName);
            return s;
        }


        public void ReadConfig(Action<string> callback, string fileName)
        {
            ResourceManager.Instance.LoadConfigResource(fileName, (textAsset) =>
            {

                if (textAsset == null)
                {
                    Debug.LogError("open json failed xmlname = " + fileName);
                }

                string content = textAsset.text;
                callback?.Invoke(content);

            });
        }









        public JObject ReadBinary<T>(string Path, string bundleName = "ConfigBin/") where T : class, new()
        {
            return ReadBinaryJSON<T>(Path, bundleName);
        }

        private JObject ReadBinaryJSON<T>(string fileName, string bundleName) where T : class, new()
        {
            TextAsset textAsset = Resources.Load(bundleName + fileName, typeof(TextAsset)) as TextAsset;

            if (textAsset == null)
            {
                Debug.LogError("open xml failed xmlname = " + fileName);
                return null;
            }

            string content = textAsset.text;

            JObject j = new JObject(content);
            return j;

        }


        /*
        public bool ReadConfig<T>(string path, System.Action<T> rowHandler, string bundleName = "config.bundle", bool immediately = false)
        {
            return ReadPlainXml<T>(path, rowHandler, bundleName, immediately);
        }

        // 编辑器模式下采用明文 XML 读取
        // 发包时需要把XML转成二进制读取
        private bool ReadPlainXml<T>(string path, System.Action<T> rowHandler, string bundleName, bool immediately)
        {
            //const string XmlConfigBundle = "config.bundle";
            //const string XmlConfigAssetPrefix = "Assets/Config/";

            //path = string.Format("{0}{1}", XmlConfigAssetPrefix, path);
            //TextAsset data = ResourceManager.LoadAsset<TextAsset>(path);

            var type = typeof(T);

            XmlDocument doc = ConfigComponent.GetDocument(path, bundleName);

            Action action = (() =>
            {
                if (doc == null)
                    return;

                var table = doc.SelectSingleNode("Table");
                if (table == null)
                    return;

                var rows = table.SelectNodes("Row");

                for (int i = 0; i < rows.Count; i++)
                {
                    var row = rows[i] as XmlElement;
                    if (row == null)
                        continue;

                    T rowInstance = (T)System.Activator.CreateInstance(typeof(T));
                    if (rowInstance == null)
                        return;

                    var attribs = row.Attributes;

                    for (int j = 0; j < attribs.Count; j++)
                    {
                        var attribName = attribs[j].Name;
                        var attribVal = attribs[j].Value;

                        FieldInfo field = type.GetField(attribName);
                        if (null == field)
                            continue;

                        GameTools.SetField(field, rowInstance, attribVal);
                    }

                    rowHandler(rowInstance);
                }
            });

            if (immediately)
                action();
            else
                actionList.Add(action);
            return true;
        }

        List<Action> actionList = new List<Action>();
        */
    }
}